/**
*   @file quadTreeADT.h
*   Interface para quadTreeADT.c.
* 	Incluye estructuras y typedefs.
*   Fecha de ultima modificacion 06/11/2007.
*/

#ifndef _quadTreeADT_h
#define _quadTreeADT_h

#include "../hashADT/hash.h"


/**
*	\typedef quadADT
* 	Puntero al tipo concreto de dato del arbol.
*/ 
typedef struct quadCDT * quadADT;

/**
*	\typedef ElementT
* 	Definicion del tipo de dato del arbol.
*/ 
typedef	void * ElementT;


/**
*	\typedef pole
* 	Enumerativo que representa la coordenada de cada nodo con respecto a su padre
*/ 
typedef enum {N, S, E, O} pole;


/**
*	\typedef fnCpyCmp
* 	Definicion del prototipo de la funcion de copia
* 	para realizar Deep Copy.
*/
typedef int (* fnCpyCmp)(ElementT, ElementT);

/**
*	\typedef fnFree
* 	Definicion del prototipo de la funcion de liberacion
* 	para liberar copias realizadas por la funcion de copia.
*/
typedef void (* fnFree)(ElementT);

/**
*	\fn NewQuad
*	Inicializa el quadTree. Se debe ejecutar antes que cualquier otra
*	funcion del ADT. Setea las funciones de liberacion, copiado y comparacion
*	de los elementos del nodo hoja. Devuelve un puntero a la raiz del quadTree.
* 	De no poder crearse, devuelve un puntero NULL.Creacion de la cola. Esta implementacion usa Deep Copy.
*   @param elementSize tamanio del elemento a guardar en el arbol.
*   @param freeElement Funcion de liberacion del elemento.
*   @param copyElement Funcion de copia del elemento.
*   @param cmpElement Funcion de comparacion del elemento.  
*   @return queueADT puntero al CDT si todo esta bien, NULL en caso contrario.
*/
quadADT NewQuad(int elementSize, fnFree freeElement, fnCpyCmp copyElement, fnCpyCmp cmpElement);

/**
*	\fn insertLeaf
*	Inserta un nodo hoja respetando la estructura del quadTree. La funcion
* 	recibe el quadTree al que se le desea agregar el nodo hoja, el quadcode del nodo,
* 	y el dato que contendra. Devuelve un 1 si el nodo hoja fue exitosamente insertado
* 	o 0 en caso contrario. Si los nodos intermedios (antecesores del nodo hoja a insertar),
* 	no existen, estos son automaticamente creados y enlazados correctamente con la raiz.
*   @param qtree qtree creado con NewQuad.
*   @param quadcode String que contiene el quadCode del elemento a ingresar.
*   @param color Elemento a insertar.
*   @return 1 si todo esta bien, 0 en caso contrario.
*/
int insertLeaf(quadADT qtree, char * quadcode, ElementT color);

/**
*	\fn getElement
*	Dado un quadcode que deberia apuntar a una hoja del quadtree, devuelve el puntero al color
* 	que tiene esa hoja, de no encontrar la hoja o bien,	que no exista el color devuelve NULL.
*   @param qtree qtree creado con NewQuad.
*   @param quadcode String que contiene el quadCode del elemento a ingresar.
*   @return ElementT si todo esta bien, NULL en caso contrario.
*/
ElementT getElement(quadADT qtree, char * quadcode);

/**
*	\fn swapQPoles
*	Dado un quadtree, swapea los nodos de un mismo nivel y mismo padre
* 	en base al criterio impuesto por fpole y spole. Estos criterios
* 	definen si se intercambian los nodos Norte con Sur o Este con Oeste.
* 	Si se intercambian N-S, entonces el swap es el siguiente:
* 	[NW <-> SW, NE <-> SE], caso contrario sera  [NW <-> NE, SW <-> SE].
* 	La combinacion de polos deberia ser valida, solo se aceptan:
* 	[pole1 = N, pole2 = S o pole1 = E, pole2 = O].
* 	Swapea todos los nodos del mismo nivel y mismo padre segun el parametro orientation.
*   @param qtree qtree creado con NewQuad.
* 	@param fpole  
* 	@param spole
* 	@return 1 si todo esta bien, 0 en caso contrario.
*/
int swapQPoles(quadADT qtree, pole fpole, pole spole);


/**
*	\fn rotateQPoles
*	Swapea todos los nodos del mismo nivel y mismo padre segun
* 	el parametro orientation.
*   @param qtree qtree creado con NewQuad.
* 	@param orientation 1 si es de manera horaria, 0 de manera antihoraria.
* 	@return 1 si todo esta bien, 0 en caso contrario.
*/
int rotateQPoles(quadADT qtree, int orientation);

/**
*	\fn hashLeafs
*	Inserta las hojas del arbol en una tabla de hash usando hashADT.
*   @param hashtable tabla de hash.
* 	@param qtree qtree creado con NewQuad.
*   @param totalpixels Cantidad de pixeles de la imagen.
*   @return 1 si todo esta bien, 0 en caso contrario.
*/
int hashLeafs(hashADT hashtable, quadADT qtree, int totalpixels);

/**
*	\fn freeQtree
*	Libera el quadTree completo.
*   @param qtree qtree creado con NewQuad.
*/
void freeQtree(quadADT qtree);

#endif
